home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3Df.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-16  |  37.1 KB  |  1,562 lines

  1. /*
  2. **      $VER: graphics3Df.c 10.11 (02.03.98)
  3. **
  4. **      Main functions for graphics3D.library
  5. **    PARTE #1
  6. **
  7. **      (C) Copyright 97 Patrizio Biancalani
  8. **      All Rights Reserved.
  9. **      
  10. **    Note: this code is traslate from the blitzbasic 3d graphics engine 
  11. **          V 0.9 of Maciej R. Gorny.
  12. **
  13. */
  14.  
  15. #include <exec/types.h>
  16. #include <exec/memory.h>
  17. #include <proto/exec.h>
  18. #include <proto/intuition.h>
  19. #include <intuition/intuition.h>
  20. #include <intuition/screens.h>
  21.  
  22. #include <graphics/rastport.h>
  23. #include <graphics/clip.h>
  24. #include <graphics/regions.h>
  25. #include <graphics/gfx.h>
  26. #include <graphics/gfxmacros.h>
  27. #include <graphics/layers.h>
  28.  
  29. #include "graphics3Dc.h"
  30. #include "graphics3D.h"
  31. #include "graphics3D2d.h"
  32. #include "graphics3Df_proto.h"
  33. #include "graphics3D2d_proto.h"
  34.  
  35.  /* Please note, that &Graphics3dBase always resides in register __a6 as well,
  36.     but if we don't need it, we need not reference it here.
  37.  
  38.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  39.     so you usually should only *pass* parameters there, but make a copy
  40.     directly after entering the function. To avoid problems of kind
  41.     "implementation defined behaviour", you should make a copy of A6 too,
  42.     when it is actually used.
  43.  
  44.     In this example case, scratch register saving would not have been 
  45.     necessary (since there are no other function calls inbetween), but we 
  46.     did it nevertheless.
  47.   */
  48.  
  49. extern void buildlookuptables(struct ambient3d *in);
  50. extern void createworldtocamera(struct ambient3d *in);
  51. extern void recalcobj(struct ambient3d *in);
  52. extern long int t_removeobject(struct ambient3d *in);
  53. extern void localtoworld(struct ambient3d *in);
  54. extern void worldtocamera(struct ambient3d *in);
  55. extern void removebackfacesandshade(struct ambient3d *in);
  56. extern void clipobject3d(struct ambient3d *in);
  57. extern void generatepolylist(struct ambient3d *in);
  58. extern struct objectnode *resetobj(struct ambient3d *in);
  59. extern struct objectnode *nextobj(struct ambient3d *in);
  60. extern struct objectnode *pobj(struct ambient3d *in);
  61. extern void aggobj(struct ambient3d *in);
  62. extern void matidentity4x4(struct matrix4x4 *imatrix); 
  63. extern void matzero4x4(struct matrix4x4 imatrix);
  64. extern void matcopy4x4(struct matrix4x4 *s_m,struct matrix4x4 *d_m);
  65. extern void matmult4x4(struct matrix4x4 *a,struct matrix4x4 *b,
  66.         struct matrix4x4 *r);
  67. extern void matmult4x4s(struct matrix4x4 *a,struct matrix4x4 *b,
  68.         struct matrix4x4 *r);
  69. extern void matmult1x4s(struct matrix1x4 *a,struct matrix4x4 *b,
  70.         struct matrix1x4 *r);
  71. extern void makevector3d(struct vertex *a,struct vertex *b,
  72.          struct vector *result);
  73. extern long int vectormag3d(struct vector *a);
  74. extern void normalpol(struct vertex *v0,struct vertex *v1,
  75.      struct vertex *v2,struct vector *normal);
  76. extern long int dotproduct(struct vector *u,struct vector *v);
  77. extern long int sqri(long int v);
  78. extern long int abs(long int val);
  79. extern void qsort(long int lo0,long int hi0,long int *pol,long int *count);
  80. extern void paintpol(struct ambient3d *in,long int *iwp,
  81.     long int total_polys,long int colb); 
  82. extern long int quicksort(long int len,long int *pol);
  83. extern void GD_deleteobject(REG(a0)struct ambient3d *in);
  84.  
  85. /**********************************************************/
  86.  
  87. long int v_worldp(struct ambient3d *in);
  88.  
  89. /****************************************************
  90.  ** Routin per la gestione della grafica, in stile **
  91.  ** 2.0                                            ** 
  92.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  93.  ****************************************************/
  94.  
  95. /************ FUNZIONI 3D ********************************/
  96.  
  97. /** macro ad uso interno e provvisorio **/
  98. #define mver(val) (val*sizeof(Svertex)+10)
  99. #define mobj(val) (val*sizeof(Sobjectnode)+5)
  100. #define mplf(val) (val*sizeof(long int)+5)
  101. #define mtmp(val) (val*sizeof(Spolytemp)+5)
  102. #define tang (361*4+5)
  103. /****************************************/
  104.  
  105. /************************************************
  106.  * apertura e inizializzazione dell'ambiente 3D * 
  107.  * restituisce puntatore ad area generale da    *
  108.  * indicare sempre al richiamo delle altre      *
  109.  * routin.                    *
  110.  ************************************************
  111.  *** INPUT :                    *
  112.  * win  -> puntatore a finestra su cui si vuol  *
  113.  *         operare.                *
  114.  * x0   -> coord. X origine finestra di vis.    *
  115.  * y0   -> coord. Y origine finestra di vis.    *
  116.  * scrw -> larghezza finestra per mondo 3D.     *
  117.  * scrh -> altezza finestra per mondo 3D.       *
  118.  * vdist-> distanza tra osservatore e piano di  *
  119.  *         proiezione.                    *
  120.  *** OUTPUT:                    *
  121.  * puntatore a struttura ambient3d da usarsi in *
  122.  * ingresso di quasi tutte le altre funzioni.   *
  123.  * > 0 allora tutto ok.                *
  124.  * <=0 allora errore, operazione fallita.       * 
  125.  ************************************************/
  126. struct ambient3d *GD_display3d(win,x0,y0,scrw,scrh,vdist)
  127. REG(a0)struct Window *win;
  128. REG(d0)long int x0;
  129. REG(d1)long int y0;
  130. REG(d2)long int scrw;
  131. REG(d3)long int scrh;
  132. REG(d4)long int vdist;
  133. {
  134. long int i;
  135. char *p;
  136. struct ambient3d *ris;
  137. struct vector *vt;
  138. struct dir3d *dan3;
  139. struct Screen *sc;
  140. struct Layer *la;
  141. struct RastPort *rp;
  142. struct tag3d *gpal;
  143.  
  144. #ifdef DEBUG
  145. char dbg[80];
  146. #endif
  147.  
  148. ris=NULL;
  149.  
  150. ris=(struct ambient3d *)AllocMem(sizeof(Sambient3d),NULL);
  151. #ifdef DEBUG
  152. sprintf(dbg,"ambient3d=%ld\n",ris);
  153. write_dbg(dbg);
  154. #endif
  155. if ((long int)ris==NULL)
  156.     {
  157.     GD_close_display3d(ris);
  158.     return(0);
  159.     }
  160.  
  161. /** inizializzo tutti i puntatori a 0 */
  162. ris->graf=0;
  163. ris->temp=0;
  164. ris->iobjects=0;
  165. ris->objects=0;
  166. ris->iwpolys=0;
  167. ris->worldpolys=0;
  168. ris->sintable=0;
  169. ris->costable=0;
  170.  
  171. p=(char *)ini_g(win,5,scrw,scrh);
  172. #ifdef DEBUG
  173. sprintf(dbg,"ini_g=%ld\n",p);
  174. write_dbg(dbg);
  175. #endif
  176. if (p==(char *)NULL)
  177.     {
  178.     GD_close_display3d(ris);
  179.     return(0);
  180.     }
  181. ris->graf=(struct grafica *)p;
  182.  
  183. i=mver(MAXVERT);
  184. if (i<(100+sizeof(Sedge)*2*MAXDY)) i=100+2*MAXDY*sizeof(Sedge);
  185. p=(char *)AllocMem(i,NULL);
  186. if (p==(char *)NULL)
  187.     {
  188.     GD_close_display3d(ris);
  189.     return(0);
  190.     }
  191. ris->temp=p;
  192. #ifdef DEBUG
  193. sprintf(dbg,"temp=%ld\n",p);
  194. write_dbg(dbg);
  195. #endif
  196.  
  197. ris->ltemp=i;
  198.  
  199. p=(char *)AllocMem(mobj(MAXOBJECT),NULL);
  200. if (p==(char *)NULL)
  201.     {
  202.     GD_close_display3d(ris);
  203.     return(0);
  204.     }
  205. ris->objects=(struct objectnode *)p;
  206.  
  207. p=(char *)AllocMem(tang,NULL);
  208. #ifdef DEBUG
  209. sprintf(dbg,"sintable=%ld\n",p);
  210. write_dbg(dbg);
  211. #endif
  212. if (p==(char *)NULL)
  213.     {
  214.     GD_close_display3d(ris);
  215.     return(0);
  216.     }
  217. ris->sintable=(long int *)p;
  218.  
  219. p=(char *)AllocMem(tang,NULL);
  220. #ifdef DEBUG
  221. sprintf(dbg,"costable=%ld\n",p);
  222. write_dbg(dbg);
  223. #endif
  224. if (p==(char *)NULL)
  225.     {
  226.     GD_close_display3d(ris);
  227.     return(0);
  228.     }
  229. ris->costable=(long int *)p;
  230.  
  231. /** inizializzo tutte le variabili **/
  232. ris->win=win;
  233. ris->half_screen_width=(ris->graf->clipdx)/2;
  234. ris->half_screen_height=(ris->graf->clipdy)/2;
  235. ris->zoom=FIXV;
  236. ris->aspect_ratio=1*FIXV;
  237. ris->inv_aspect_ratio=1*FIXV;
  238. ris->viewing_distance=vdist;
  239. new_fov(ris);
  240. ris->minx=x0;
  241. ris->miny=y0;
  242. ris->maxx=ris->graf->clipdx;
  243. ris->maxy=ris->graf->clipdy;
  244. ris->agg_all=1;
  245. ris->gl_triangle_color=1;
  246. ris->gcolor=0;
  247. ris->ambient_light=1*FIXV;
  248. ris->projection_type=PROSP_P;
  249. vt=&ris->light_source;
  250.  
  251. vt->x=234;     /* =INT(0.913913*FIXV) */
  252. vt->y=100;     /* =INT(0.389759*FIXV) */
  253. vt->z=-29;     /* =INT(-0.113369*FIXV)*/
  254. vt->w=0;
  255.  
  256. /*
  257. vt->x=1*FIXV;
  258. vt->y=-2*FIXV;
  259. vt->z=5*FIXV;
  260. vt->w=0*FIXV;
  261. */
  262. vt=&ris->view_point;
  263. vt->x=1*FIXV;
  264. vt->y=2*FIXV;
  265. vt->z=3*FIXV;
  266. vt->w=10*FIXV;
  267. dan3=&ris->view_angle;
  268. dan3->angx=0;
  269. dan3->angy=0;
  270. dan3->angz=0;
  271. ris->near_z=ris->viewing_distance;
  272. ris->far_z=4096;
  273. ris->bord_col=1;
  274. ris->fzbuf=0;
  275. ris->clip_mode=ZPLANE;
  276. ris->view_mode=WIREF;
  277. ris->maxintensity=ris->graf->n_level-1;
  278. ris->total_polys=0;
  279. ris->max_polys=0;
  280. ris->old_mpoly=0;
  281. ris->total_objects=0;
  282. ris->attuale=0;
  283. ris->numero=1;
  284.  
  285. /* genero tutte sfumature di grigio di default */
  286. gpal=(struct tag3d *)(ris->temp+15000);
  287. gpal[0].tipo=GP_COL;
  288. gpal[0].val=0L;
  289. gpal[1].tipo=END_T;
  290. GD_genpalette(ris,gpal);
  291.  
  292. /* installo una clipregion, per effettuare il clip automatico */
  293. i=clipbox(ris->graf,ris->minx,ris->miny,ris->maxx,ris->maxy);
  294. #ifdef DEBUG
  295. sprintf(dbg,"clipbox esi=%ld\n",i);
  296. write_dbg(dbg);
  297. #endif
  298. if (i==NULL)
  299.     {
  300.     GD_close_display3d(ris);
  301.     return(0);
  302.     }    
  303.  
  304. /** inizializzo tabelle seno e coseno **/
  305. buildlookuptables(ris);
  306.  
  307. return(ris);
  308.  
  309. }
  310.  
  311. /************************************************
  312.  * chiusura ed eliminazione dell'ambiente 3D    * 
  313.  ************************************************
  314.  *** INPUT :                    *
  315.  * in -> valore >0 restituito da display3d.     *
  316.  *** OUTPUT:                    *
  317.  * nessuno.                    *
  318.  ************************************************/
  319. void GD_close_display3d(in)
  320. REG(a0)struct ambient3d *in;
  321. {
  322. long int i,n;
  323.  
  324. if (in==NULL) return(0);
  325.  
  326. if (in->temp!=NULL) FreeMem(in->temp,in->ltemp);
  327. if (in->sintable!=NULL) FreeMem(in->sintable,tang);
  328. if (in->costable!=NULL) FreeMem(in->costable,tang);
  329. if (in->iwpolys!=NULL) FreeMem(in->iwpolys,mplf(in->max_polys));
  330. if (in->worldpolys!=NULL) FreeMem(in->worldpolys,mtmp(in->max_polys));
  331. if (in->total_objects>NULL)
  332.     {
  333.     n=in->total_objects;
  334.     for(i=0 ; i<n ; i++)
  335.         {
  336.         in->attuale=0;    
  337.         GD_deleteobject(in);
  338.         }
  339.     }
  340. if (in->iobjects!=NULL) FreeMem(in->iobjects,NULL);
  341. if (in->objects!=NULL) FreeMem(in->objects,mobj(MAXOBJECT));
  342. if (in->graf!=NULL) close_g(in->graf);
  343.     
  344. FreeMem(in,sizeof(Sambient3d));
  345.  
  346. }
  347.  
  348. /********************************************
  349.  ** cambia il modo di visualizzazione      **
  350.  ** globale.                   **
  351.  ********************************************
  352.  *** INPUT :                    *
  353.  * in  -> valore >0 restituito da display3d.*
  354.  * modo-> modalita' di visualizzazione      *
  355.  *        oggetti.                *
  356.  *        WIREF  = wire frame               *
  357.  *        SOLID  = solid shade           *
  358.  *        FLAT   = flat shading            *
  359.  *      GORAUD = goraud shading        *
  360.  * b_col-> colore bordo, se <0 allora nessun*
  361.  *        bordo per i poligoni.            *
  362.  *** OUTPUT:                     *
  363.  * >0 tutto ok.                    *
  364.  * =0 valore non valido.            *
  365.  ********************************************/
  366. long int GD_changeviewmode(in,modo,b_col)
  367. REG(a0)struct ambient3d *in;
  368. REG(d0)long int modo;
  369. REG(d1)long int b_col;
  370. {
  371. struct objectnode *obj;
  372. long int buf,md;
  373.  
  374. in->bord_col=b_col;
  375. md=0x0F & modo;
  376.  
  377. if (md!=WIREF AND md!=SOLID AND md!=FLAT AND md!=GORAUD) return(0);
  378.  
  379. buf=in->attuale;
  380. obj=resetobj(in);
  381. while(obj!=NULL)
  382.     {
  383.     obj->shade=modo;
  384.     obj->trasf|=0x01;
  385.     obj=nextobj(in);
  386.     }
  387.  
  388. in->view_mode=modo;
  389. in->attuale=buf;
  390.  
  391. return(1);
  392. }
  393.  
  394. /**********************************************
  395.  ** genera tutta la palette dei colori in    **
  396.  ** in modo indipendente dai valori impostati**
  397.  ** DA USARSI AL POSTO DELLA TOUCHPALETTE .  **
  398.  **********************************************
  399.  *** INPUT :                     **
  400.  * in -> valore > 0 restituito da display3d   *
  401.  * new-> puntatore a array di strutture          *
  402.  *      tag3d con nuovi valori.          *
  403.  **** OUTPUT:                     **
  404.  * 0 == nessuna variazione .              *
  405.  * 0 >  n# di variazioni effettuate.          *
  406.  *** NOTE :                     **
  407.  **********************************************/
  408. long int GD_genpalette(in,new)
  409. REG(a0)struct ambient3d *in;
  410. REG(a1)struct tag3d *new;
  411. {
  412. long int *col,ris,i,ii,ct,ft,n_col,color;
  413. long int d_red,d_green,d_blu;
  414. long int red,green,blu;
  415. long int *tcol;
  416. struct rgbtype *crgb,*c;
  417. struct grafica *graf;
  418. #ifdef DEBUG
  419. char dbg[200];
  420. #endif
  421.  
  422. n_col=0;
  423. ris=0;
  424.  
  425. col=(long int *)in->temp;
  426. crgb=(struct rgbtype *)&col[260];
  427. graf=(struct grafica *)in->graf;
  428. tcol=graf->t_color;
  429.  
  430. for (i=0 ; i<256 ; i++)
  431.     {
  432.     col[i]=-1;
  433.     ct=i<<1;
  434.     crgb[ct].r=15;
  435.     crgb[ct].g=15;
  436.     crgb[ct].b=15;
  437.     crgb[ct+1].r=0;
  438.     crgb[ct+1].g=0;
  439.     crgb[ct+1].b=0;
  440.     }
  441.  
  442. ct=0;
  443. while(new[ct].tipo!=END_T AND ct<300)
  444.     {
  445.     ft=new[ct].tipo;
  446.     i=new[ct].val;
  447.     switch(ft)
  448.         {
  449.         case (GP_RCOL):
  450.         /* riservo un n# di colori non utilizzato */
  451.         /* uso multiplo di 2 piu' vicino */
  452.         if (((i+1)>>1)<<1 < graf->depth)
  453.             {
  454.             graf->r_color=((i+1)>>1)<<1;
  455.             ris++;
  456.             }
  457.         break;
  458.  
  459.         case (GP_NCOL):
  460.         /* definisco il n# di colori base da usare */
  461.         if (i > 0)
  462.             {
  463.             ii=i;
  464.             if (ii>graf->depth-graf->r_color) ii=graf->depth-graf->r_color;
  465.             graf->n_color=ii;
  466.             ris++;
  467.             }
  468.         break;
  469.  
  470.         case (GP_NLIV):
  471.         /* definisco il n# di livelli di intensita' per ogni colore */        
  472.         if (i > 0)
  473.             {
  474.         /* verifico se n# livelli troppo grande se si lo adeguo automaticamente*/
  475.             ii=i;
  476.             if (ii*graf->n_color > graf->depth-graf->r_color) 
  477.                 ii=(graf->depth-graf->r_color)/graf->n_color;
  478.             graf->n_level=ii;
  479.             ris++;
  480.             }
  481.         break;
  482.  
  483.         case (GP_COL):
  484.         /* assegno il n# di colore virtuale a cui associare la prossima seq. rgb */
  485.         if (i < graf->n_color)
  486.             {
  487.             n_col=i;
  488.             col[n_col]=i;
  489.             tcol[n_col]=graf->r_color+(n_col*graf->n_level);
  490.             ris++;
  491.             }
  492.         break;
  493.  
  494.         case (GP_HRGB):
  495.         /* livello RGB massimo da usare per definire il n# di colore richiesto */
  496.         /* BIANCO SE NON DEFINITA */
  497.         c=(struct rgbtype *)i;
  498.         crgb[n_col<<1].r=c->r;
  499.         crgb[n_col<<1].g=c->g;
  500.         crgb[n_col<<1].b=c->b;
  501.         ris++;
  502.         break;
  503.  
  504.         case (GP_LRGB):
  505.         /* livello RGB minimo da usare per definire il n# di colore richiesto */
  506.         /* NERO SE NON DEFINITA */
  507.         c=(struct rgbtype *)i;
  508.         crgb[(n_col<<1)+1].r=c->r;
  509.         crgb[(n_col<<1)+1].g=c->g;
  510.         crgb[(n_col<<1)+1].b=c->b;
  511.         ris++;
  512.         break;
  513.  
  514.         case (GP_PALET):
  515.         /* assegna al colore indicato in GP_COL il registro della palette indicato*/
  516.         if (i <= graf->depth)
  517.             {
  518.             tcol[n_col]=i;
  519.             col[n_col]=-1;    
  520.             ris++;
  521.             }        
  522.         break;
  523.         
  524.         case (GP_TRASP) :
  525.         /* assegna il colore trasparente all'ultimo colore e non verra' considerato per i
  526.            livelli di luminosita' */
  527.         tcol[graf->n_color-1]=TRASP;
  528.         col[graf->n_color-1]=-1;
  529.         graf->n_level=(graf->depth-graf->r_color)/(graf->n_color-1);
  530.         ris++;
  531.         break;
  532.     
  533.         case (GP_INFO):
  534.         /* ritorna in .val il n# di registro nella palette assegnato a quel colore */
  535.         /* val deve essere puntatore ad intero */
  536.         *(long int *)i=tcol[n_col];        
  537.         ris++;
  538.         break;
  539.         
  540.         }
  541.     ct++;
  542.     }
  543.  
  544. in->maxintensity=graf->n_level-1;
  545.  
  546. /* genero la palette dei livelli dei colori definiti */
  547. for (i=0 ; i<256 ;i++)
  548.     {
  549.     if (col[i]>=NULL)
  550.         {
  551.         n_col=col[i]<<1;
  552.         color=tcol[col[i]];
  553. #ifdef DEBUG
  554. sprintf(dbg,"color=%ld\n",color);
  555. write_dbg(dbg);
  556. #endif
  557.         ft=0;
  558.         if (crgb[n_col].r>15 OR crgb[n_col].g>15 OR crgb[n_col].b>15) ft=1;
  559.         if (crgb[n_col+1].r>15 OR crgb[n_col+1].g>15 OR crgb[n_col+1].b>15) ft=1;
  560.         red=crgb[n_col+1].r<<8;
  561.         green=crgb[n_col+1].g<<8;
  562.         blu=crgb[n_col+1].b<<8;            
  563.         d_red=((crgb[n_col].r<<8)-red)/graf->n_level;
  564.         d_green=((crgb[n_col].g<<8)-green)/graf->n_level;
  565.         d_blu=((crgb[n_col].b<<8)-blu)/graf->n_level;
  566.         for (ct=0 ;ct<graf->n_level; ct++)
  567.             {
  568.             if (ft)
  569.                 {
  570.                 if (color+ct<graf->depth)
  571.                     SetRGB32(graf->vpor,color+ct,(red>>8)<<24,
  572.                         (green>>8)<<24,(blu>>8)<<24);
  573.                 }
  574.             else
  575.                 {
  576.                 if (color+ct<graf->depth)
  577.                     SetRGB4(graf->vpor,color+ct,red>>8,green>>8,blu>>8);
  578.                 }
  579.             red+=d_red;
  580.             green+=d_green;
  581.             blu+=d_blu;
  582.             }
  583.         }
  584.     }
  585.  
  586. return(ris);
  587. }
  588.  
  589. /**********************************************
  590.  ** crea una palette sfumata tra due colori  **
  591.  ** nella palette dello schermo, in modo di  **
  592.  ** poter poi usare il FLAT E il GORAUD      **
  593.  ** SHADING.                            **
  594.  **********************************************
  595.  *** INPUT :                      * 
  596.  * in -> valore > 0 restituito da display3d.  *
  597.  * fr -> n# primo registro colore da settare. *
  598.  * lr -> n# ultimo reg. colore da settare.    *
  599.  * init_color -> punt. a struttura rgbtype    *
  600.  *               con valore rgb iniz. colore. *
  601.  * last_color -> punt. a struttura rgbtype    *
  602.  *         con valore rgb fin. color.   *
  603.  *** OUTPUT:                      *
  604.  * nessuno.                      *
  605.  *** NOTE :                      *
  606.  * se si usa valori tra 0-15 per i colori si  *
  607.  * puo' usare la graphics.library del S.O.2.0 *
  608.  * altrimenti occorre il 3.0.              *
  609.  **********************************************/
  610. void GD_touchpalette(in,fr,lr,init_color,last_color)
  611. REG(a0)struct ambient3d *in;
  612. REG(d0)long int fr;
  613. REG(d1)long int lr;
  614. REG(a1)struct rgbtype *init_color;
  615. REG(a2)struct rgbtype *last_color;
  616. {
  617. long int i,c;
  618. struct tag3d *gpal;
  619.  
  620. gpal=(struct tag3d *)(in->temp+15000);
  621.  
  622. c=fr/in->graf->n_level - in->graf->r_color;
  623.  
  624. if (c>in->graf->n_color-1) c=in->graf->n_color-1;
  625.  
  626. gpal[0].tipo=GP_COL;
  627. gpal[0].val=c;
  628. gpal[1].tipo=GP_HRGB;
  629. gpal[1].val=(long int)last_color;
  630. gpal[2].tipo=GP_LRGB;
  631. gpal[2].val=(long int)init_color;
  632. gpal[3].tipo=END_T;
  633.  
  634. GD_genpalette(in,gpal);
  635.  
  636. }
  637.  
  638. /**********************************************
  639.  ** muove l'osservatore di dist unita'       **
  640.  **********************************************
  641.  *** INPUT :                      * 
  642.  * in -> valore > 0 restituito da display3d.  *
  643.  * dist -> numero di unita' di spostamento.   *
  644.  *         (il valore deve essere FIXPOINT)   *
  645.  *** OUTPUT:                      *
  646.  * nessuno.                      *
  647.  **********************************************/
  648. void GD_moveforward(in,dist)
  649. REG(a0)struct ambient3d *in;
  650. REG(d0)long int dist;
  651. {
  652. long int *sin,*cos;
  653. struct dir3d *vang;
  654. struct vector *vp;
  655. long int active_axes,dx,dy,dz;
  656.  
  657. sin=in->sintable;
  658. cos=in->costable;
  659. vang=&in->view_angle;
  660. vp=&in->view_point;
  661.  
  662. active_axes=0;
  663.  
  664. if (vang->angx!=NULL) active_axes+=1;
  665. if (vang->angy!=NULL) active_axes+=2;
  666. if (vang->angz!=NULL) active_axes+=4;
  667.  
  668. switch (active_axes)
  669.     {
  670.     case (0):
  671.         dx=0;
  672.         dy=0;
  673.         dz=dist;
  674.         break;
  675.     case (1):
  676.         dx=0;
  677.         dy=(dist*cos[vang->angx]) >> SFIXV;
  678.         dz=(dist*sin[vang->angx]) >> SFIXV;
  679.         break;
  680.     case (2):
  681.         dx=(dist*sin[vang->angy]) >> SFIXV;
  682.         dy=0;
  683.         dz=(dist*cos[vang->angy]) >> SFIXV;
  684.         break;
  685.     case (3):
  686.         dx=(dist*sin[vang->angy]) >> SFIXV;
  687.         dy=(dist*cos[vang->angx]) >> SFIXV;
  688.         dz=(dist*cos[vang->angy]) >> SFIXV + 
  689.             (dist*sin[vang->angx]) >> SFIXV;
  690.         break;
  691.     case (4):        
  692.         dx=(dist*sin[vang->angz]) >> SFIXV;
  693.         dy=(dist*cos[vang->angz]) >> SFIXV;
  694.         dz=0;
  695.         break;        
  696.     case (5):
  697.         dx=(dist*sin[vang->angz]) >> SFIXV;
  698.         dy=(dist*cos[vang->angx]) >> SFIXV +
  699.             (dist*cos[vang->angz]) >> SFIXV;    
  700.         dz=(dist*sin[vang->angx]) >> SFIXV;
  701.         break;
  702.  
  703.     case (6):
  704.         dx=(dist*sin[vang->angy]) >> SFIXV +
  705.             (dist*sin[vang->angz]) >> SFIXV;
  706.         dy=(dist*cos[vang->angz]) >> SFIXV;
  707.         dz=(dist*cos[vang->angy]) >> SFIXV;
  708.         break;
  709.  
  710.     case (7):
  711.         dx=(dist*sin[vang->angy]) >> SFIXV +
  712.             (dist*sin[vang->angz]) >> SFIXV;    
  713.         dy=(dist*cos[vang->angx]) >> SFIXV +
  714.             (dist*cos[vang->angz]) >> SFIXV;    
  715.         dz=(dist*sin[vang->angx]) >> SFIXV +
  716.             (dist*cos[vang->angy]) >> SFIXV;
  717.         break;    
  718.  
  719.     }
  720.  
  721. vp->x+=dx;
  722. vp->y+=dy;
  723. vp->z+=dz;
  724.  
  725. /* forzo aggiornamento di TUTTA la scena */
  726. in->agg_all=1;
  727.  
  728. }
  729.  
  730. /**********************************************
  731.  ** cambio l'angolo della visuale            **
  732.  **********************************************
  733.  *** INPUT :                      * 
  734.  * in -> valore > 0 restituito da display3d.  *
  735.  * ax -> valore rotazione su asse x.          *
  736.  *       (in gradi e intero)              *
  737.  * ay -> valore rotazione su asse y.          *
  738.  *       (in gradi e intero)              *
  739.  * az -> valore rotazione su asse z.          *
  740.  *       (in gradi e intero)              *
  741.  *** OUTPUT:                      *
  742.  * nessuno.                      *
  743.  **********************************************/
  744. void GD_viewangle(in,ax,ay,az)
  745. REG(a0)struct ambient3d *in;
  746. REG(d0)long int ax;
  747. REG(d1)long int ay;
  748. REG(d2)long int az;
  749. {
  750. struct dir3d *va;
  751.  
  752. va=&in->view_angle;
  753.  
  754. if (ax<0 OR ax>360)
  755.     {
  756.     ax-=(ax/360)*360;
  757.     if (ax<0) ax+=360;
  758.     }
  759.  
  760. if (ay<0 OR ay>360)
  761.     {
  762.     ay-=(ay/360)*360;
  763.     if (ay<0) ay+=360;
  764.     }
  765.  
  766. if (az<0 OR az>360)
  767.     {
  768.     az-=(az/360)*360;
  769.     if (az<0) az+=360;
  770.     }
  771.  
  772. va->angx=ax;
  773. va->angy=ay;
  774. va->angz=az;
  775.  
  776. /* forzo aggiornamento di TUTTA la scena */
  777. in->agg_all=1;
  778.  
  779. }
  780.  
  781. /******************************************************
  782.  ** setta i piani near e far del volume visualizzato **
  783.  ******************************************************
  784.  *** INPUT :                          * 
  785.  * in   -> valore > 0 restituito da display3d.          *
  786.  * near -> posizione piano vicino.(valore intero)     *
  787.  * far  -> posizione piano lontano.(valore intero)    *
  788.  *** OUTPUT:                          *
  789.  * nessuno.                          *
  790.  ******************************************************/
  791. void GD_frustum(in,near,far)
  792. REG(a0)struct ambient3d *in;
  793. REG(d0)long int near;
  794. REG(d1)long int far;
  795. {
  796. long int n,f;
  797. /* i valori in input devono essere interi */
  798. n=near;
  799. f=far;
  800. /*if (near<in->viewing_distance) n=in->viewing_distance;*/
  801. if (far<near) f=2*n;
  802.  
  803. in->near_z=n;
  804. in->far_z=f;
  805.  
  806. }
  807.  
  808. /******************************************************
  809.  ** crea e posiziona una sorgente di luce .          **
  810.  ******************************************************
  811.  *** INPUT :                          * 
  812.  * in -> valore > 0 restituito da display3d.          *
  813.  * x  -> valore coordinata X luce(valore FIXPOINT).   *
  814.  * y  -> valore coordinata Y luce(valore FIXPOINT).   *
  815.  * z  -> valore coordinata Z luce(valore FIXPOINT).   *
  816.  *** OUTPUT:                          *
  817.  * nessuno.                          *
  818.  ******************************************************/
  819. void GD_createlightsource(in,x,y,z)
  820. REG(a0)struct ambient3d *in;
  821. REG(d0)long int x;
  822. REG(d1)long int y;
  823. REG(d2)long int z;
  824. {
  825. struct vertex v1,v2;
  826. long int dd;
  827.  
  828. /* i valori in ingresso devono gia' essere in fixpoint */
  829. v2.x=x;
  830. v2.y=y;
  831. v2.z=z;
  832. v1.x=0;
  833. v1.y=0;
  834. v1.z=0;
  835.  
  836. makevector3d(&v1,&v2,&in->light_source);
  837.  
  838. /* riduco l'ampiezza del vettore ma non la direzione che l'unica cosa che serve*/
  839. dd=in->light_source.x;
  840. if (dd<in->light_source.y) dd=in->light_source.y;
  841. if (dd<in->light_source.z) dd=in->light_source.z;
  842. dd=dd>>SFIXV;
  843. if (dd==NULL) dd=1;
  844. if (dd<NULL) dd=-dd;
  845.  
  846. in->light_source.x/=dd;
  847. in->light_source.y/=dd;
  848. in->light_source.z/=dd;
  849.  
  850. /* forzo aggiornamento scena */
  851. in->agg_all=1;
  852.  
  853. }
  854.  
  855. /**********************************************
  856.  ** setta l'intensita' di luce ambientale.   **
  857.  **********************************************
  858.  *** INPUT :                      * 
  859.  * in  -> valore > 0 restituito da display3d. *
  860.  * inte-> valore intensita' luce (positivo)   *
  861.  *       (valore in FIXPOINT).              *
  862.  *** OUTPUT:                      *
  863.  * nessuno.                      *
  864.  **********************************************/
  865. void GD_ambientlight(in,inte)
  866. REG(a0)struct ambient3d *in;
  867. REG(d0)long int inte;
  868. {
  869. long int i;
  870. i=inte;
  871.  
  872. /* il valore di input deve essere in fixpoint */
  873. if (i>>SFIXV > in->maxintensity) i=in->maxintensity<<SFIXV;
  874. if (i<NULL) i=0;
  875. in->ambient_light=i;
  876.  
  877. /* forzo aggiornamento scena */
  878. in->agg_all=1;
  879.  
  880. }
  881.  
  882. /************************************************
  883.  ** posiziona il punto di vista nel mondo 3d.  ** 
  884.  ************************************************
  885.  *** INPUT :                        * 
  886.  * in -> valore > 0 restituito da display3d.    *
  887.  * x  -> valore coordinata X camera        *
  888.  *     (valore FIXPOINT).                 *
  889.  * y  -> valore coordinata Y camera        *
  890.  *       (valore FIXPOINT).               *
  891.  * z  -> valore coordinata Z camera        *
  892.  *       (valore FIXPOINT).               *
  893.  *** OUTPUT:                    *
  894.  * nessuno.                    *
  895.  ************************************************/
  896. void GD_positioncamera(in,x,y,z)
  897. REG(a0)struct ambient3d *in;
  898. REG(d0)long int x;
  899. REG(d1)long int y;
  900. REG(d2)long int z; 
  901. {
  902.  
  903. /* i valori in input devono gia' essere in fixpoint */ 
  904. in->view_point.x=x;
  905. in->view_point.y=y;
  906. in->view_point.z=z;
  907.  
  908. /* forzo aggiornamento scena */
  909. in->agg_all=1;
  910.  
  911. }
  912.  
  913. /************************************************
  914.  ** variazione aspect ratio scena.            **
  915.  ************************************************
  916.  *** INPUT :                        * 
  917.  * in -> valore > 0 restituito da display3d.    *
  918.  * ratio-> nuovo aspect ratio.(valore FIPOINT). *
  919.  *** OUTPUT:                    *
  920.  * nessuno.                    *
  921.  ************************************************/
  922. void GD_aspectratio(in,ratio)
  923. REG(a0)struct ambient3d *in;
  924. REG(d0)long int ratio;
  925. {
  926.  
  927. in->aspect_ratio=ratio;
  928. in->inv_aspect_ratio=FIXV*FIXV/ratio;
  929.  
  930. new_fov(in);
  931.  
  932. }
  933.  
  934. /************************************************
  935.  ** setta un particolare modo per il clipping. **
  936.  ************************************************
  937.  *** INPUT :                        * 
  938.  * in -> valore > 0 restituito da display3d.    *
  939.  * mode -> nuovo modo di clipping.        *
  940.  *         (ZPLANE ,FRUSTUM).            *
  941.  *** OUTPUT:                    *
  942.  * nessuno.                    *
  943.  ************************************************/
  944. void GD_clipmode(in,mode)
  945. REG(a0)struct ambient3d *in;
  946. REG(d0)long int mode;
  947. {
  948.  
  949. in->clip_mode=mode;
  950. if (mode!=FRUSTUM AND mode!=ZPLANE) in->clip_mode=ZPLANE;
  951.  
  952. }
  953.  
  954. /*************************************
  955.  ** ROUTIN PER CABIARE IL COLORE    **
  956.  ** DI UN REGISTRO DELLA PALETTE    **
  957.  *************************************
  958.  **** INPUT :                **
  959.  ** graf ->valore non 0 ritornato da**
  960.  **        display3d.            **
  961.  ** nr   ->numero registro da       **
  962.  **        variare.            **
  963.  ** red  ->livello rosso (0-15).    **
  964.  ** green->livello verde (0-15).    **
  965.  ** blue ->livello blu   (0-15).    **
  966.  **** OUTPUT:                **
  967.  ** nessuno.                **
  968.  *************************************/
  969. void GD_rgb4(REG(a0)struct ambient3d *in,REG(d0)long int n,
  970.     REG(d1)long int red,REG(d2)long int green,REG(d3)long int blue) 
  971. {
  972.  
  973. }
  974.  
  975. /******************************************************
  976.  ** visualizza effettivamente i poligoni nella frame **
  977.  ** corrente. Ordina i poligoni in base alla Z min.  **
  978.  ** o se attivo usa lo Z buffering.             **
  979.  ******************************************************
  980.  *** INPUT :                          * 
  981.  * in -> valore > 0 restituito da display3d.          *
  982.  *** OUTPUT:                          *
  983.  * puntatore a RastPort su cui si e' disegnato.          *
  984.  * In caso di libreria ottimizzato e' quello della    *
  985.  * finestra di visualizzazione.                  *
  986.  ******************************************************/
  987. struct RastPort *GD_paintframe(in)
  988. REG(a0)struct ambient3d *in;
  989. {
  990. long int it,buf;
  991.  
  992. it=0;
  993.  
  994. /* ripulisco la frame attuale */
  995. cls_f(in);
  996.  
  997. if (in->total_objects==NULL OR in->iwpolys==NULL) return(in->graf->rast);
  998.  
  999. /** riordino tutti i poligoni in base alla loro distanza **/
  1000. /** dall'osservatore.                     **/
  1001. /** si effettua solo se lo ZBUFFERING e' OFF          **/
  1002. /** ho usato il quicksort                 **/
  1003. if (in->fzbuf==NULL) it=quicksort(in->total_polys,in->iwpolys);
  1004.  
  1005. buf=in->graf->rast->DrawMode;
  1006.  
  1007. over(in->graf,1);
  1008.  
  1009. /** inizio la visualizzazione vera e propia della frame attuale **/
  1010. paintpol(in,in->iwpolys,in->total_polys,in->bord_col);
  1011.  
  1012. over(in->graf,buf);
  1013.  
  1014. return (in->graf->rast);
  1015. }
  1016.  
  1017. /**********************************************
  1018.  ** ri-calcola la vista del mondo 3d.        **
  1019.  **********************************************
  1020.  *** INPUT :                      * 
  1021.  * in -> valore > 0 restituito da display3d.  *
  1022.  *** OUTPUT:                      *
  1023.  * nessuno.                      *
  1024.  **********************************************/
  1025. void GD_newview(in)
  1026. REG(a0)struct ambient3d *in;
  1027. {
  1028. struct objectnode *obj;
  1029. long int buf;
  1030.  
  1031. #ifdef DEBUG
  1032. char dbg[80];
  1033. #endif
  1034.  
  1035. createworldtocamera(in);
  1036.  
  1037. /* resetlist() */
  1038. buf=in->attuale;
  1039. obj=resetobj(in);
  1040.  
  1041. if (in->total_objects>NULL)
  1042. {
  1043.  
  1044.    if (in->old_mpoly<=in->max_polys)
  1045.     {
  1046. /* se e' aumentato il n# massimo di poligoni nello spazio allora vario le aree coinvolte */
  1047.     if (v_worldp(in)==NULL)
  1048.         {
  1049.         /* se fallisce riprovo con le dimensioni vecchie */
  1050.         in->max_polys=in->old_mpoly;
  1051.         if (v_worldp(in)==NULL)
  1052.             {
  1053.             /* se fallisce di nuovo termino */
  1054.             return(0);
  1055.             }
  1056.         }
  1057.     else
  1058.         {
  1059.         in->old_mpoly=in->max_polys;
  1060.         }
  1061.     }
  1062.  
  1063. #ifdef DEBUG
  1064. sprintf(dbg,"*** INIZIO RICALCOLO SCENA ***\n");
  1065. write_dbg(dbg);
  1066. #endif
  1067.  
  1068.    do
  1069. /** non cambiare l'ordine d'esecuzione delle routin in questo loop MAI! **/
  1070.     {
  1071.     GD_recalcobj(in);
  1072.     if (obj->trasf!=NULL OR in->agg_all!=NULL)    
  1073.         {
  1074.         if (t_removeobject(in)==NULL)
  1075.             {
  1076.             localtoworld(in);
  1077.             removebackfacesandshade(in);
  1078.             worldtocamera(in);
  1079.             clipobject3d(in);
  1080.             }
  1081.         }
  1082. /*  reset segnalazione di trasformazioni multiple */
  1083.     obj->trasf=0;
  1084.     obj=nextobj(in);
  1085.     }while(obj!=NULL);
  1086.  
  1087. #ifdef DEBUG
  1088. sprintf(dbg,"*** FINE RICALCOLO SCENA ***\n\n");
  1089. write_dbg(dbg);
  1090. #endif
  1091.  
  1092.    generatepolylist(in);
  1093. #ifdef DEBUG
  1094. sprintf(dbg,"Generatepolylist\n");
  1095. write_dbg(dbg);
  1096. #endif
  1097.  
  1098. }
  1099. /* resetto flag per forzare aggiornamento scena */
  1100.    in->agg_all=0;
  1101.  
  1102. /* ripristino oggetto attualmente selezionato */
  1103.    in->attuale=buf;
  1104.  
  1105. }
  1106.  
  1107. /********************************************************************************/
  1108. /* funzione locale per ridefinire le aree per i poligoni proiettati nella scena */ 
  1109. /********************************************************************************/
  1110. long int v_worldp(struct ambient3d *in)
  1111. {
  1112.  
  1113. if (in->max_polys==NULL) return(0);
  1114.  
  1115. if (in->iwpolys!=NULL) FreeMem(in->iwpolys,mplf(in->old_mpoly));
  1116. in->iwpolys=(long int *)AllocMem(mplf(in->max_polys),NULL);
  1117. if (in->iwpolys==NULL) 
  1118.     {
  1119.     if (in->worldpolys!=NULL) FreeMem(in->worldpolys,mtmp(in->old_mpoly));
  1120.     in->worldpolys=0;
  1121.     return(0);
  1122.     }
  1123.     
  1124. if (in->worldpolys!=NULL) FreeMem(in->worldpolys,mtmp(in->old_mpoly));
  1125. in->worldpolys=(struct polytemp *)AllocMem(mtmp(in->max_polys),NULL);
  1126. if (in->worldpolys==NULL) 
  1127.     {
  1128.     FreeMem(in->iwpolys,mplf(in->max_polys));
  1129.     in->iwpolys=0;
  1130.     return(0);
  1131.     }
  1132.  
  1133. return(1);
  1134. }
  1135.  
  1136. /********** FUNZIONI 2D *************************/
  1137. /************************************
  1138.  ** FUNZIONE PER DEFINIRE UN BOX   **
  1139.  ** DI CLIP SULLA FINESTRA         **
  1140.  ************************************
  1141.  **** INPUT :               **
  1142.  ** in   -> valore >0 ritornato    **
  1143.  **         dalla funzione d'ini-  **
  1144.  **         zializzazione display3d**
  1145.  ** minx - valore minimo x box.    **
  1146.  ** miny - valore minimo y box.    **
  1147.  ** dx - larghezza box.           **
  1148.  ** dy - altezza box.           **
  1149.  **** OUTPUT:               **
  1150.  ** > 0 tutto ok valore dx.       ** 
  1151.  ** = 0 errore.               **
  1152.  **** NOTA:               **
  1153.  ** dx e dy non possono eccedere i **
  1154.  ** valori indicati in display3d() ** 
  1155.  ************************************/
  1156. long int GD_clipbox(REG(a0)struct ambient3d *in,REG(d0)long int minx,
  1157.            REG(d1)long int miny,REG(d2)long int dx,REG(d3)long int dy)
  1158. {
  1159. long int ris;
  1160. struct Window *win;
  1161.  
  1162. if (in->maxx<dx OR in->maxy<dy) return(0);
  1163.  
  1164. ris=clipbox(in->graf,minx,miny,dx,dy);
  1165. if (ris==NULL) return(ris);
  1166.  
  1167. win=in->win;
  1168.  
  1169. in->half_screen_width=ris/2;
  1170. in->half_screen_height=dy/2;
  1171. new_fov(in);
  1172. in->minx=minx;
  1173. in->miny=miny;
  1174.  
  1175. return(ris);
  1176.  
  1177. }
  1178.  
  1179. /************************************
  1180.  ** FUNZIONE PER VISUALIZZARE LA   **
  1181.  ** RASTPORT NASCOSTA SULLA        **
  1182.  ** FINESTRA.               **
  1183.  ************************************
  1184.  **** INPUT :               **
  1185.  ** in ->   valore >0 ritornato    **
  1186.  **         dalla funzione d'ini-  **
  1187.  **         zializzazione display3d**
  1188.  **** OUTPUT:               **
  1189.  ************************************/
  1190. void GD_switch_rp(in)
  1191. REG(a0)struct ambient3d *in;
  1192. {
  1193.  
  1194. switch_rp(in->graf);
  1195.  
  1196. }
  1197.  
  1198. /*****************************************
  1199.  ** FUNZIONE PER VARIARE CARATTERISTCHE **
  1200.  ** SCENA 3D.                **
  1201.  *****************************************
  1202.  **** INPUT :                **
  1203.  ** in -> valore >0 ritornato dalla     **
  1204.  **       funzione d'inizializzazione   **
  1205.  **      display3d().            **
  1206.  ** new-> puntatore a array di strutture**
  1207.  **      tag3d con nuovi valori.    **
  1208.  **** OUTPUT:                **
  1209.  ** == 0  - nessuna variazione .        ** 
  1210.  **  > 0  - n# variazioni eseguite.     ** 
  1211.  *****************************************/
  1212. long int GD_cascene(in,new)
  1213. REG(a0)struct ambient3d *in;
  1214. REG(a1)struct tag3d *new;
  1215. {
  1216. long int ris,i,ct,ft;
  1217. struct vertex *vp;
  1218.  
  1219. ris=0;
  1220. ct=0;
  1221.  
  1222. while(new[ct].tipo!=END_T AND ct<1000)
  1223.     {
  1224.     ft=new[ct].tipo;
  1225.     i=new[ct].val;
  1226.     switch(ft)
  1227.         {
  1228.         case(CS_PROJET):
  1229.     /* cambio tipo di proiezione */
  1230.             if (i==PROSP_P OR i==PARAL_P)
  1231.                 {
  1232.                 in->projection_type=i;
  1233.                 in->agg_all=1;    
  1234.                 ris+=1;
  1235.                 }
  1236.             break;
  1237.  
  1238.         case(CS_ZOOM):
  1239.     /* cambio valore zoom scena */
  1240.             if (i<256*FIXV)
  1241.                 {
  1242.                 in->zoom=i;            
  1243.                 in->agg_all=1;
  1244.                 ris+=1;
  1245.                 }
  1246.             break;
  1247.  
  1248.         case(CS_VDIST):
  1249.     /* sposto distanza osservatore dal piano di proiezione */
  1250.                 in->viewing_distance=i;
  1251.                 in->agg_all=1;
  1252.                 ris+=1;
  1253.             break;
  1254.  
  1255.         case(CS_VIEWP):
  1256.     /* inserisce nella struttura vertex puntata da .val la posizione attuale della camera */
  1257.         if (i!=NULL)
  1258.             {
  1259.             vp=(struct vertex *)i;
  1260.             vp->x=in->view_point.x;    
  1261.             vp->y=in->view_point.y;
  1262.             vp->z=in->view_point.z;
  1263.             ris+=1;
  1264.             }
  1265.         break;
  1266.  
  1267.         case(CS_NPX0):
  1268.     /* sposto X0 box scena 3d nella sua finestra */
  1269.             in->minx=i;
  1270.             clipbox(in->graf,in->minx,in->miny,
  1271.                 in->graf->clipdx,in->graf->clipdy);
  1272.             in->agg_all=1;
  1273.             ris+=1;
  1274.             break;
  1275.  
  1276.         case(CS_NPY0):
  1277.     /* sposto Y0 box scena 3d nella sua finestra */
  1278.             in->miny=i;
  1279.             clipbox(in->graf,in->minx,in->miny,
  1280.                 in->graf->clipdx,in->graf->clipdy);
  1281.             in->agg_all=1;
  1282.             ris+=1;
  1283.             break;
  1284.     
  1285.         case(CS_GCOLOR):
  1286.     /* cambio colore fondo a scena 3d */
  1287.             in->gcolor=i;
  1288.             in->agg_all=1;
  1289.             ris+=1;
  1290.             break;
  1291.             
  1292.         case(CS_ZBUF):
  1293.     /* setto flag per zbuffer come indicato */
  1294.         if (i!=NULL) i=c_zbuf(in);
  1295.         in->fzbuf=i;
  1296.         in->agg_all=1;
  1297.         ris+=1;
  1298.         break;
  1299.  
  1300.         }
  1301.     ct+=1;
  1302.     }
  1303.  
  1304. new_fov(in);
  1305.  
  1306. return(ris);
  1307. }
  1308.  
  1309. /*************************************
  1310.  ** FUNZIONE PER PASSARE DA INTERO  **
  1311.  ** A FIXPOINT.                **
  1312.  *************************************
  1313.  **** INPUT :                **
  1314.  ** in -> puntatore a intero long   **
  1315.  **       con valore da convertire. **
  1316.  ** out-> puntatore a intero long   **
  1317.  **       con valore convertito.    **
  1318.  **** OUTPUT:                **
  1319.  ** ==0 -> tutto ok.            **
  1320.  ** <>0 -> errore out non modificato**
  1321.  *************************************/
  1322. long int GD_int2fix(in,out)
  1323. REG(a0)long int *in;
  1324. REG(a1)long int *out;
  1325. {
  1326. long int bf,bf1;
  1327.  
  1328. bf=in[0];
  1329.  
  1330. /* calcolo massimo valore convertibile */
  1331. bf1=0x7fffffff >> SFIXV;
  1332.  
  1333. if (bf>bf1) return (1);
  1334. if (bf<-bf1) return (2);
  1335.  
  1336. out[0]=bf << SFIXV;
  1337.  
  1338. return(0);
  1339.  
  1340.  
  1341. /*************************************
  1342.  ** FUNZIONE PER PASSARE DA SINGLE  **
  1343.  ** FLOAT A FIXPOINT.            **
  1344.  *************************************
  1345.  **** INPUT :                **
  1346.  ** in -> puntatore a single float  **
  1347.  **       con valore da convertire. **
  1348.  ** out-> puntatore a intero long   **
  1349.  **       con valore convertito.    **
  1350.  **** OUTPUT:                **
  1351.  ** ==0 -> tutto ok.            **
  1352.  ** <>0 -> errore out non modificato**
  1353.  *************************************/
  1354. long int GD_sfl2fix(in,out)
  1355. REG(a0)float *in;
  1356. REG(a1)long int *out;
  1357. {
  1358. long int max,it,frt;
  1359. float ifix;
  1360.  
  1361. it=in[0];
  1362. ifix=FIXV;
  1363.  
  1364. /* calcolo massimo valore convertibile */
  1365. max=0x7fffffff >> SFIXV;
  1366.  
  1367. if (it>=max) return (1);
  1368. if (it<=-max) return (2);
  1369.  
  1370. out[0]=in[0]*ifix;
  1371.  
  1372. return(0);
  1373.  
  1374.  
  1375. }
  1376.  
  1377. /*************************************
  1378.  ** FUNZIONE PER PASSARE DA DOUBLE  **
  1379.  ** FLOAT A FIXPOINT.            **
  1380.  *************************************
  1381.  **** INPUT :                **
  1382.  ** in -> puntatore a double float  **
  1383.  **       con valore da convertire. **
  1384.  ** out-> puntatore a intero long   **
  1385.  **       con valore convertito.    **
  1386.  **** OUTPUT:                **
  1387.  ** ==0 -> tutto ok.            **
  1388.  ** <>0 -> errore out non modificato**
  1389.  *************************************/
  1390. long int GD_dfl2fix(in,out)
  1391. REG(a0)double *in;
  1392. REG(a1)long int *out;
  1393. {
  1394. long int max,it,frt;
  1395. double ifix;
  1396.  
  1397. it=in[0];
  1398. ifix=FIXV;
  1399.  
  1400. /* calcolo massimo valore convertibile */
  1401. max=0x7fffffff >> SFIXV;
  1402.  
  1403. if (it>=max) return (1);
  1404. if (it<=-max) return (2);
  1405.  
  1406. out[0]=in[0]*ifix;
  1407.  
  1408. return(0);
  1409.  
  1410.  
  1411. }
  1412.  
  1413. /*************************************
  1414.  ** FUNZIONE PER PASSARE DA FIXPOINT**
  1415.  ** AD INTERO                ** 
  1416.  *************************************
  1417.  **** INPUT :                **
  1418.  ** in -> puntatore a intero long   **
  1419.  **       con valore da convertire. **
  1420.  ** out-> puntatore a intero long   **
  1421.  **       con valore convertito.    **
  1422.  **** OUTPUT:                **
  1423.  ** ==0 -> tutto ok.            **
  1424.  ** <>0 -> errore out non modificato**
  1425.  *************************************/
  1426. long int GD_fix2int(in,out)
  1427. REG(a0)long int *in;
  1428. REG(a1)long int *out;
  1429. {
  1430. long int i;
  1431.  
  1432. i=in[0];
  1433. if (i<~0L - FIXVM) i=i+FIXVM;
  1434.  
  1435. out[0]=i >> SFIXV;
  1436.  
  1437. return(0);
  1438.  
  1439. }
  1440.  
  1441. /*************************************
  1442.  ** FUNZIONE PER PASSARE DA FIXPOINT**
  1443.  ** AD SINGLE FLOAT            ** 
  1444.  *************************************
  1445.  **** INPUT :                **
  1446.  ** in -> puntatore a intero long   **
  1447.  **       con valore da convertire. **
  1448.  ** out-> puntatore a single float  **
  1449.  **       con valore convertito.    **
  1450.  **** OUTPUT:                **
  1451.  ** ==0 -> tutto ok.            **
  1452.  ** <>0 -> errore out non modificato**
  1453.  *************************************/
  1454. long int GD_fix2sfl(in,out)
  1455. REG(a0)long int *in;
  1456. REG(a1)float *out;
  1457. {
  1458. float fv,ifix;
  1459.  
  1460. ifix=FIXV;
  1461. fv=in[0];
  1462.  
  1463. out[0]=fv/ifix;
  1464.  
  1465. return(0);
  1466.  
  1467. }
  1468.  
  1469. /*************************************
  1470.  ** FUNZIONE PER PASSARE DA FIXPOINT**
  1471.  ** AD DOUBLE FLOAT            ** 
  1472.  *************************************
  1473.  **** INPUT :                **
  1474.  ** in -> puntatore a intero long   **
  1475.  **       con valore da convertire. **
  1476.  ** out-> puntatore a double float  **
  1477.  **       con valore convertito.    **
  1478.  **** OUTPUT:                **
  1479.  ** ==0 -> tutto ok.            **
  1480.  ** <>0 -> errore out non modificato**
  1481.  *************************************/
  1482. long int GD_fix2dfl(in,out)
  1483. REG(a0)long int *in;
  1484. REG(a1)double *out;
  1485. {
  1486. double fv,ifix;
  1487.  
  1488. ifix=FIXV;
  1489. fv=in[0];
  1490.  
  1491. out[0]=fv/ifix;
  1492.  
  1493. return(0);
  1494.  
  1495. }
  1496.  
  1497. /*************************************
  1498.  ** FUNZIONE PER CAMBIARE IL MODO   **
  1499.  ** VIDEO DI TRACCIAMENTO.          **
  1500.  *************************************
  1501.  **** INPUT :                       **
  1502.  ** in   -> valore >0 ritornato da  **
  1503.  **         display3d().            **
  1504.  ** mod  -> nuovo modo video.       **
  1505.  **** NOTA :                **
  1506.  ** valori per mod :            **
  1507.  ** 0 > JAM1 (over 2)            **
  1508.  ** 1 > JAM2 (over 0) (def.)        **
  1509.  ** 2 > COMPLEMENT (over 1)         **
  1510.  ** 4 > INVERSVID  (inverse 1)      **
  1511.  *************************************/
  1512. void GD_over(REG(a0)struct ambient3d *in,REG(d0)long int mod)
  1513. {
  1514.  
  1515. over(in->graf,mod);
  1516.  
  1517. }
  1518.  
  1519. /*************************************
  1520.  ** FUNZIONE PER CANCELLARE UN BOX  **
  1521.  ** NELLA FINESTRA .            **
  1522.  *************************************
  1523.  **** INPUT :                       **
  1524.  ** in   -> valore >0 ritornato da  **
  1525.  **         display3d().            **
  1526.  ** x0   -> coord. x punto in alto  **
  1527.  **         a sinistra box.         **
  1528.  ** y0   -> coord. y punto in alto  **
  1529.  **         a sinistra box.         **
  1530.  ** x1   -> coord. x punto in basso **
  1531.  **         a destra box.        **
  1532.  ** y1   -> coord. y punto in basso **
  1533.  **        a destra box.        **
  1534.  **** NOTA :                **
  1535.  ** usa il colore dello sfondo, e   **
  1536.  ** non influenza le altre funzioni **
  1537.  *************************************/
  1538. void GD_cls_b(REG(a0)struct ambient3d *in,REG(d0)long int x0,
  1539.     REG(d1)long int y0,REG(d2)long int x1,REG(d3)long int y1)
  1540. {
  1541. /*
  1542. cls_b(in->graf,x0,y0,x1,y1);
  1543. */
  1544. }
  1545.  
  1546. /***************** FINE ROUTIN USABILI ESTERNAMENTE ********************/
  1547.  
  1548. /**************************************
  1549.  ** RICALCOLO VALORI FOV_WIDTH e     **
  1550.  ** FOV_HEIGHT.                 **
  1551.  **************************************/
  1552. void new_fov(struct ambient3d *in)
  1553. {
  1554.  
  1555. in->fov_w=((in->half_screen_width + FOV_M) << SFIXV)/
  1556.     ((in->viewing_distance*in->zoom) >> SFIXV);
  1557. in->fov_h=((in->half_screen_height + FOV_M) * in->inv_aspect_ratio)/ 
  1558.     ((in->viewing_distance*in->zoom) >> SFIXV);
  1559.  
  1560. }
  1561.